import 'package:dio/dio.dart';
import 'package:dio_smart_retry/dio_smart_retry.dart';
import 'package:flutter/foundation.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';

import '../ApiConfig.dart';

class DioUtils {
  DioUtils._privateConstructor();

  DioUtils() {
    // 仅debug模式下打印日志
    dio = Dio(BaseOptions(
      baseUrl: ApiConfig.getBaseUrl(),
      connectTimeout: const Duration(seconds: 300),
      receiveTimeout: const Duration(seconds: 300),
      sendTimeout: const Duration(seconds: 300),
      contentType: Headers.jsonContentType,
      followRedirects: true,
    ));
    // 除了release模式外，其余都显示请求日志
    if (!kReleaseMode) {
      dio?.interceptors.add(PrettyDioLogger(
          requestHeader: true,
          requestBody: true,
          responseBody: true,
          responseHeader: false,
          error: true,
          compact: true,
          maxWidth: 90));
    }
    dio?.interceptors.add(RetryInterceptor(dio: dio! , retries: 3 , retryDelays: [
      const Duration(seconds: 3),
      const Duration(seconds: 3),
      const Duration(seconds: 3),
    ]));
    // dio?.interceptors.add(ServerHandlerInterceptor());
  }

  Dio? dio;

  Dio? _streamDio;

  static DioUtils? _instance;

  static DioUtils getInstance() {
    _instance ??= DioUtils();
    return _instance!;
  }

  getStreamDio(){
    _streamDio = Dio();
    if(dio != null){
      _streamDio?.options = dio!.options;
      _streamDio?.interceptors.addAll(dio!.interceptors);
    }
    _streamDio?.options.responseType = ResponseType.stream;
    return _streamDio;
  }


  /// 请求头之类的内容都可以放进options来传递
  get(url, {Map<String, dynamic>? data, Options? options}) {
    return dio?.get(url, queryParameters: data, options: options);
  }

  /// 请求头之类的内容都可以放进options来传递
  post(url, {Map<String, dynamic>? data, Options? options}) {
    return dio?.post(url, data: data , options: options);
  }



  /// 退出登录时使用
  void removeAuth() {
    dio?.options.headers.remove('Authorization');
  }

  /// 文件下载
  Future<Response>? downLoad(
      String url, String savePath, ProgressCallback callback,
      {CancelToken? cancelToken}) {
    return dio?.download(url, savePath,
        onReceiveProgress: callback, cancelToken: cancelToken);
  }
}
